# -*- coding: utf-8 -*-
# © 2018 QYT Technology
# Authored by: Zhao Xingtao (zxt50330@gmail.com)
from transitions.extensions import HierarchicalMachine as Machine
from bills import db


class StateMachineModel(db.Model):
    """ 状态机模型
    :cvar __states__: 定义一系列状态，格式为双元素元组: (0, 'INITIALIZING')
    :cvar __transitions__: 定义状态迁移的trigger
    :cvar __state_children_mapping__: 某个状态的子状态映射，为字典格式， key为父状态， value为对应的relationship名称
    """
    __abstract__ = True

    __states__ = []
    __transitions__ = []
    __state_children_mapping__ = {}
    __custom_triggers__ = tuple()

    status = db.Column(db.SmallInteger, index=True, default=0, nullable=False, doc=u'状态值')

    def __init__(self, **kwargs):
        super(StateMachineModel, self).__init__(**kwargs)
        self._finished = False
        self._pending_log = {}
        self._tracker = None
        self._custom_triggers = self._load_custom_triggers()
        self.init_state_machine()

    @db.reconstructor
    def init_state_machine(self):
        if not db.session.is_active:
            return
        if self.status is None:
            self.status = 0

        self._pending_log = {}
        self._tracker = None
        self._custom_triggers = self._load_custom_triggers()

        initial = self._get_initial()
        machine = Machine(model=self,
                          states=self._get_states(),
                          transitions=self.get_transitions(),
                          auto_transitions=False,
                          initial=initial,
                          send_event=True,
                          )

        for s, rel in self.__state_children_mapping__.items():
            machine.on_enter(s, lambda *args, **kwargs: self._init_obj_for_state(rel=rel))
        setattr(self, 'fsm', machine)
        # logger.debug('State machine initialized for %s' % self)